package com.hotelManagerSystem.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author treasy
 */
@Configuration
public class ShiroConfig {
    /*@Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }*/
    //解决第一次登录时url带jsessionid的问题
    @Bean
    public DefaultWebSessionManager sessionManager(){
        DefaultWebSessionManager sessionManager=new DefaultWebSessionManager();
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }
    //自定义密码加密方式
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher=new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//设置加密方式为md5
        hashedCredentialsMatcher.setHashIterations(1024);//设置加密次数
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }
    //自定义realm
    @Bean
    public ShiroRealmAdmin shiroRealmAdmin(){
        ShiroRealmAdmin shiroRealmAdmin = new ShiroRealmAdmin();
        //将自定义加密方式注入容器
        shiroRealmAdmin.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealmAdmin;
    }
    @Bean
    public ShiroRealmCustomer shiroRealmCustomer(){
        ShiroRealmCustomer shiroRealmCustomer=new ShiroRealmCustomer();
        //将自定义加密方式注入容器
        shiroRealmCustomer.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealmCustomer;
    }
    @Bean
    public ModularRealmAuthorizer modularRealmAuthorizer(){
        return new ShiroRealmAuthorizer();
    }

    //系统自带的Realm管理，主要针对多realm认证
    @Bean
    public ModularRealmAuthenticator modularRealmAuthenticator(){
        ShiroRealmAuthenticator shiroRealmAuthenticator = new ShiroRealmAuthenticator();
        shiroRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return shiroRealmAuthenticator;
    }
    @Bean("securityManager")
    public DefaultWebSecurityManager securityManager(){
        System.out.println("securityManager被调用");
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        List<Realm> realms = new ArrayList<>();
        realms.add(shiroRealmAdmin());
        realms.add(shiroRealmCustomer());
        //授权
        securityManager.setAuthorizer(modularRealmAuthorizer());
        //认证
        securityManager.setAuthenticator(modularRealmAuthenticator());//需要在设置realm前进行设置
        securityManager.setRealms(realms);
        //设置会话管理器
        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }
    //创建shiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        //创建拦截器
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //shiro过滤规则
        Map<String,String> filterMap=new LinkedHashMap<>();
        //filterMap.put("/view/login","anon");
        filterMap.put("/view/customer-login","anon");
        filterMap.put("/customer/login","anon");
        filterMap.put("/view/admin-login","anon");
        filterMap.put("/admin/login","anon");
        filterMap.put("/static/**","anon");
        filterMap.put("/**","authc");
        //项目启动修改登陆页面
        shiroFilterFactoryBean.setLoginUrl("/view/customer-login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/view/customer-login");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }
}
